<?
/**
 * IGNITE - the request cycle handler.
 *
 * This is the most used class - altough the less communicative one.
 * This class controls the general request cycle, both front- and back-office. Virtually all requests include this document.
 * The IGNITE class controls the session structure, the root location and the type of handling (front / CMS), both as the DB class construct and the general stand-alone functions.
 *
 * Please read the LICENSE file
 * @license 	GNU Lesser General Public License
 * @copyright 	oneDot only <we@onedotonly.be>
 * @author 		Koen Betsens <koen@onedotonly.be>
 *
 * @package 	Global
 */

/**
 * IGNITE class.
 *
 * This class controls the general request cycle, both front- and back-office. Virtually all requests include this document.
 * The IGNITE class controls the session structure, the root location and the type of handling (front / CMS), both as the DB class construct and the general stand-alone functions.
 *
 * @package 	Global
 *
 * @return		object	if requested (optional behaviour), the path related engine class derivate is returned (equals IGNITE::engine )
 */
class IGNITE	{
	
	/**
	 * Define path structures: relative root working path 
	 *
	 * @name working_loc	defines part of global constant ENGINE_CORE 
	 */
	const working_loc	= "engine/www/";
	
	/**
	 * Define path structures: relative root class path 
	 *
	 * @name classes_loc	defines part of PHP's internal __autoload class locator 
	 */
	const classes_loc	= "class/";
	
	/**
	 * Cookie expire time 
	 *
	 * @name cookie_expire	in seconds, default is 30 days. 
	 */
	const cookie_expire	= 2592000;

	/**
	 * The current working location
	 *
	 * @var	string
	 */
	private $dirstring;

	/**
	 * The exploded working location
	 *
	 * @var	array
	 */
	 private $dir;
	 
	/**
	 * The basic standard DB retreived settings
	 *
	 * @var	array
	 */
	 static $settings_global = array( "account", "theme", "langs", "url" );
	
	/**
	 * Constructs the Engine object
	 *
	 * @return	object	if requested (optional behaviour), the path related engine class derivate is returned (equals IGNITE::engine )
	 */
 	function __construct(){
		
		$this->dir = explode( "/", $this->dirstring = getcwd());
		
		return $this->engine();

	}
	 
	/**
	 * Start the request cycle
	 *
	 * Start the request cycle - session cycle, dynamic session caching and language retreival, base ENGINE class retreival, Account an working paths and account level DB setup.
	 *
	 * @return	void
	 */	
	public function cycle(  ) {
		global $DB, $_account_override, $dir;
		
#		is session controlled
		session_start();

#		include root ENGINE class
		require_once( "ENGINE.php" );
		
#		define working location
		$dir = explode( "/", $dirstring = getcwd());

		if( !( $_account_override )
		&&  !$_account_override = $_SESSION[ ENGINE::session_init ][ "account" ] )
	 		 $_account_override = $dir[( $keys = array_keys( $dir, ENGINE::cp_dir ))?
	 		 							 array_pop( $keys ) -1: array_pop( array_keys( $dir, ENGINE::public_dir )) -1 ];

#		Set up the global constants
		self::global_constants( $dirstring );

#		Load DB variables and account-level settings
		require_once( ROOT . ACCOUNT ."/custom.root/.inflame" );

#		create main Database class
		$DB = new DB( $dbhost, $dbuser, $dbpass, $dbname );


#		Session control: initiate or reset session when called for
		if( !isset( $_SESSION[ ENGINE::session_init ] ) || isset( $_GET[ "fresh" ]))
	
				self::fresh();
		else 	define( "LANG", $_SESSION[ ENGINE::session_init ][ "lang" ], true );

	}
	
	/**
	 * Retreive current Engine class ( front / CMS / Core )
	 *
	 * @return	object	the path related engine class derivate.
	 */	
	public function engine() {
		global $dir;

		
#		FRONTEND vs. BACKEND
		switch( end( $dir )) {
			case ENGINE::public_dir		:
				
				$Engine =  new ROOM();
				break;

			default			:
				
				$Engine = new CORE();
				break;
		}
		
		
		return $Engine;
	}


	/**
	 * Global constants, kept to a comfortable minimum
	 *
	 * @return	void
	 */	
	private function global_constants( $dirstring )	{
		global $_account_override;
		
#		Define cycle constants (these are always accessible)
		define( "ACCOUNT",		$_account_override, true );
		define( "ROOT",			array_shift( explode( ACCOUNT, $dirstring )), true );
		define( "ENGINE_CORE", 	ROOT . self::working_loc, true );
		define( "IE", 			( stripos( $_SERVER[ "HTTP_USER_AGENT" ], "MSIE" ) !== false && stripos( $_SERVER[ "HTTP_USER_AGENT" ], "chromeframe" ) == false ), true);
	}
	
	
	/**
	 * Refresh or initial load all session parameters
	 *
	 * Retreives the standard DB stored settings, the user language (browser-based / stored / forced), theme force and sitemap tree.
	 *
	 * @return	void
	 */	
	private function fresh() {
		global $DB;
		
		unset( $_SESSION[ ENGINE::session_init ]);

#		Retreive DB settings
		if( $rows = $DB->query_rows( str_replace( "%0", implode( "','", self::$settings_global ), DB::Q_settings )))
			foreach( $rows as $row )
					 $_SESSION[ ENGINE::session_init ][ $row[ 'key' ]] = $row[ 'value' ];

#		Perform extra setting entries
		$_SESSION[ ENGINE::session_init ] = array_merge( $_SESSION[ ENGINE::session_init ], array( 
			
			"langmaster"	=> array_shift( explode( ",", $_SESSION[ ENGINE::session_init ][ 'langs' ])),
			"dictionary"	=> json_decode( $DB->query_direct( str_replace( "%0", engine_get( "lang.dictionary" ), DB::Q_module ))),
			"account"		=> ACCOUNT
		));
		
		
#		Force settings		
		if( !$_SESSION[ ENGINE::session_init ][ "lang" ] || isset( $_GET[ "fresh" ]))
			self::get_fresh( $_GET[ "fresh" ]);
		
		define(		"LANG", $_SESSION[ ENGINE::session_init ][ "lang" ], true);
		setcookie(	"LANG", LANG, time() + self::cookie_expire );
		
#		Add sitemap to cache
		$_SESSION[ ENGINE::session_sitemap ] = array (

			"menu"	=> $DB->filter_key( "page", "!parent && !private && active order by hierarchy", "ID, name" ),
			"num"	=> $DB->filter_key( "page", "active order by ID", array("ID", "name, active, mods, parent, private, meta, nameid, textid, <%lang:pages.nameid%> as title, (select group_concat(sp.ID order by sp.hierarchy) from pages as sp where sp.parent=pages.ID && sp.active group by sp.parent ) as sub" )),
			"str"	=> $DB->filter_key( "page", "active", array("name", "ID" ))
		);
	}
	
	/**
	 * Language and theme check.
	 *
	 * Language can be stored in cookie, forced by get variable or retreived from the user browser settings.
	 * Theme can be forced by get variable.
	 *
	 * @return	void
	 */	
	private function get_fresh( $get ) {
	
		$fresh = explode(':', $get );

		if ( $fresh[ 0 ] == "lang" )
			
			 $_SESSION[ ENGINE::session_init ][ "lang" ] = $fresh[ 1 ];
		else $_SESSION[ ENGINE::session_init ][ "lang" ] = isset( $_COOKIE[ "LANG" ] )? $_COOKIE[ "LANG" ] : self::getLanguage();
		
		if ( $fresh[ 0 ] == "theme" )
			 $_SESSION[ ENGINE::session_init ][ "theme" ] = $fresh[ 1 ];

	}
	
	/**
	 * Language retreival.
	 *
	 * Language is retreived from the user browser settings (and used incase language exists in account).
	 *
	 * @return	string	language code, user based or default
	 */	
	private function getLanguage() {
		
		$lang= ( $http_lang = $_SERVER[ "HTTP_ACCEPT_LANGUAGE" ])?
				 substr( strtolower( $http_lang ), 0, 2 ) : 'en';
		
		return ( strpos( $_SESSION[ ENGINE::session_init ][ 'langs' ], $lang ) === false)? $_SESSION[ ENGINE::session_init ][ 'langmaster' ] : $lang;
	}
	
}

?>